package client;

import java.util.ArrayList;

import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;

import protocol.domain.GroupEntry;
import protocol.generic.Group;

/**
 * the class of ProtocolClientHelper is used to 
 * parse and generate xml which is used for 
 * transmiting
 * 
 * This class is SINGLETON
 * @author wangkaidi
 *
 */
public class ProtocolClientHelper 
{
	private static ProtocolClientHelper instance;
	private ProtocolClientHelper()
	{		
	}
	
	/**
	 * return the only instance
	 * @return
	 */
	public static synchronized ProtocolClientHelper getInstance()
	{
		if(instance==null)
		{
			instance=new ProtocolClientHelper();
		}
		return instance;
	}
	
	/**
	 * get the login request xml
	 * @param username
	 * @param password
	 * @return
	 */
	public String getLoginRequest(String username,String password)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1000\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(username);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(password);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>");
		return sb.toString();
	}
	
	/**
	 * get the string which representing log out
	 * @return
	 */
	public String getLogoutRequest()
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1001\n");
		sb.append("\t</code>\n");
		sb.append("</request>");
		return sb.toString();
	}
	
	/**
	 * this method will return a string representing send a message to the dest
	 * @param to
	 * @param content
	 * @return
	 */
	public String getSendMessageString(String destid,String content)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1002\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("</arg>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(content);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>");
		return sb.toString();
	}
	
	public String getAddFriendString(String destid,String groupname)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1003\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("</arg>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(groupname);
		sb.append("\n");
		sb.append("</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getFriendInfoString()
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1004\n");
		sb.append("\t</code>\n");
		sb.append("</request>");
		return sb.toString();
	}
	
	public String getDeleteGroupString(String groupname)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1007\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(groupname);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getRenameGroupString(String oldname,String newname)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1006\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(oldname);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(newname);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getDeleteString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1009\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getDeleteFromGroupString(String group,String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1008\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(group);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");		
		return sb.toString();
	}
	
	public String getRequestString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1010\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getAgreeString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1011\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getDenyString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1012\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getBlockString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1013\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public String getUnBlockString(String destid)
	{
		StringBuffer sb=new StringBuffer();
		sb.append("<request>\n");
		sb.append("\t<code>\n");
		sb.append("\t1014\n");
		sb.append("\t</code>\n");
		sb.append("\t<arg>\n");
		sb.append("\t");
		sb.append(destid);
		sb.append("\n");
		sb.append("\t</arg>\n");
		sb.append("</request>\n");
		return sb.toString();
	}
	
	public ArrayList<String> getArgs(NodeList arglist)
	{
		ArrayList<String> list=new ArrayList<String>();
		for(int i=0;i<arglist.getLength();i++)
		{
			Node node=arglist.item(i);
			String value=node.getFirstChild().getTextContent().trim();
			list.add(value);
		}
		return list;
	}
	
	/**
	 * this method will parse the <arg> tag in the xml
	 * and generate a list of Group objects
	 * @param nodelist
	 * @return
	 */
	public ArrayList<Group> getGroups(Node node)
	{
		ArrayList<GroupEntry>temp=this.getGroupEntries(node);
		ArrayList<Group>list=new ArrayList<Group>();
		for(int i=0;i<temp.size();i++)
		{
			GroupEntry entry=temp.get(i);
			String groupname=entry.getGroupName();
			
			Group group=this.getGroup(list, groupname);
			if(group==null)//if not found,first create a groupentry
			{
				group=new Group(groupname);
				group.addGroupEntry(entry);
				list.add(group);
			}
			else//if exists,just add this groupentry
			{
				group.addGroupEntry(entry);
			}
		}
		return list;
	}
	
	/**
	 * this method will return the Group object.
	 * if not found,null will be returned
	 * @param list
	 * @param groupname
	 * @return
	 */
	private Group getGroup(ArrayList<Group>list,String groupname)
	{
		for(int i=0;i<list.size();i++)
		{
			Group group=list.get(i);
			if(group.getName().equals(groupname))
			{
				return group;
			}
		}
		return null;
	}
	
	/**
	 * change the <arg> tag in xml to a list of GroupEntry
	 * @param node
	 * @return
	 */
	private ArrayList<GroupEntry> getGroupEntries(Node node)
	{
		ArrayList<GroupEntry> list=new ArrayList<GroupEntry>();
		NodeList children=((Element)node).getElementsByTagName("groupentry");
		for(int i=0;i<children.getLength();i++)
		{
			Node tempnode=children.item(i);
			Element tempelement=(Element)tempnode;
			String alias=tempelement.getElementsByTagName("alias").item(0).getFirstChild().getTextContent();
			String id=tempelement.getElementsByTagName("id").item(0).getFirstChild().getTextContent();
			String groupname=tempelement.getElementsByTagName("groupname").item(0).getFirstChild().getTextContent();
			GroupEntry entry=new GroupEntry(alias,id,groupname,null,false);
			list.add(entry);			
		}
		return list;
	}
}
